"""Path utilities for DYVA.

- Ensures required directories exist based on config/config.yaml.
- Follows project rules: PEP8, type hints, logging (no prints).
"""
from __future__ import annotations

import logging
import os
from pathlib import Path
from typing import List, Dict, Any

import yaml


def load_config(config_path: str = "config/config.yaml") -> Dict[str, Any]:
    """Load YAML configuration safely.

    Args:
        config_path: Path to YAML config file.

    Returns:
        Parsed configuration dictionary.
    """
    with open(config_path, "r", encoding="utf-8") as f:
        return yaml.safe_load(f)


def get_required_directories(cfg: Dict[str, Any]) -> List[Path]:
    """Extract required directories from config.

    - Creates output_txt, temp_audio, logs_dir.
    - Ensures parent directory for output_csv exists.
    - Does NOT create input_videos (e.g., drive root S:/).

    Args:
        cfg: Loaded configuration dict.

    Returns:
        List of Path objects that must exist.
    """
    paths_cfg = cfg.get("paths", {})
    required: List[Path] = []

    def _p(key: str) -> Path | None:
        v = paths_cfg.get(key)
        if not v:
            return None
        return Path(v)

    output_txt = _p("output_txt")
    temp_audio = _p("temp_audio")
    logs_dir = _p("logs_dir")
    output_csv = _p("output_csv")

    for p in (output_txt, temp_audio, logs_dir):
        if p is not None:
            required.append(p)

    # Ensure parent dir for CSV path exists (e.g., data/result)
    if output_csv is not None:
        parent = output_csv.parent
        if str(parent) and parent.name:
            required.append(parent)

    # De-duplicate while preserving order
    seen = set()
    unique_required: List[Path] = []
    for p in required:
        if p not in seen:
            unique_required.append(p)
            seen.add(p)

    return unique_required


def ensure_directories(dirs: List[Path]) -> None:
    """Create directories if missing.

    Uses `exist_ok=True` to be idempotent.
    """
    for d in dirs:
        try:
            os.makedirs(d, exist_ok=True)
            logging.getLogger(__name__).info("Ensured directory: %s", d)
        except Exception as exc:
            logging.getLogger(__name__).error("Failed to ensure dir %s: %s", d, exc)
            raise


def ensure_directories_from_config(config_path: str = "config/config.yaml") -> List[Path]:
    """Convenience function to load config and ensure required directories.

    Returns the list of ensured directories for reporting.
    """
    cfg = load_config(config_path)
    dirs = get_required_directories(cfg)
    ensure_directories(dirs)
    return dirs
